package com.my.javaweb.interview.date240410.answer;

public class OrderStatusMQListener {
    private OrderService orderService;
    private PayService payService;
    private NotifyService notifyService;

    public void consume(String orderNo) {
        final OrderInfo orderInfo = orderService.getOrderInfo(orderNo);
        processOrder(orderInfo);
    }

    private void processOrder(OrderInfo orderInfo) {
        int status = orderInfo.getStatus();
        String orderBizType = orderInfo.getOrderBizType();

        // 将支付和完成订单的逻辑分别封装到 processPayment 和 processCompletion 方法中，提高代码的可读性和可维护性。
        if (OrderStatus.PAYING.getCode() == status) {
            // 执行支付业务
            processPayment(orderInfo, orderBizType);
        } else if (OrderStatus.PAY_COMPLETED.getCode() == status) {
            // 执行订单完成业务
            processCompletion(orderInfo, orderBizType);
        } else if (OrderStatus.REFUND.getCode() == status) {
            // 同意退款 待未来业务扩展......
        }
    }

    /* 支付业务 */
    private void processPayment(OrderInfo orderInfo, String orderBizType) {
        long payId = -1;
        try {
            if (PayType.HOTEL.getCode().equals(orderBizType)) {
                payPrdOfHotelVerify(orderInfo);
                payId = payService.payOfCredit(orderInfo);
            } else if (PayType.TICKETS.getCode().equals(orderBizType)) {
                for (int i = 0; i < 3; i++) {
                    payId = payService.payOfCredit(orderInfo);
                    if (payId > 0) {
                        break;
                    }
                }
            } else if (PayType.VISA.getCode().equals(orderBizType)) {
                payId = payService.payOfAliPay(orderInfo);
            }

            if (payId < 0) {
                payService.notPayedToClose(orderInfo);
            } else {
                if (PayType.VISA.getCode().equals(orderBizType)) {
                    payAfterOfVisaBusiness(payId, orderInfo);
                }
            }
        } catch (Exception e) {
            // 异常处理逻辑
        }
    }

    /*支付完成业务*/
    private void processCompletion(OrderInfo orderInfo, String orderBizType) {
        try {
            orderService.updateOrderStatus(orderInfo.getOrderNo(), OrderStatus.PAY_COMPLETED.getCode());
            processNotification(orderBizType);
        } catch (Exception e) {
            // 异常处理逻辑
        }
    }

    /*发送通知消息业务*/
    private void processNotification(String orderBizType) {
        try {
            if (PayType.HOTEL.getCode().equals(orderBizType)) {
                // 给运营发钉钉通知
                notifyService.dingding("发送到酒店运营群里的内容");
                // 给用户发短信
                notifyService.sms("发送到给酒店用户的内容");
            }
            // 门票订单
            else if (PayType.TICKETS.getCode().equals(orderBizType)) {
                // 给运营发钉钉通知
                notifyService.dingding("发送到门票运营群里的内容");
                // 给用户发短信
                notifyService.sms("发送到给门票用户的内容");
                // 给用户发微信通知
                notifyService.wechat("发送到给门票用户的内容");
            }
            // 签证订单
            else if (PayType.VISA.getCode().equals(orderBizType)) {
                // 给运营发钉钉通知
                notifyService.dingding("发送到签证运营群里的内容");
                // 给用户发微信通知
                notifyService.wechat("发送到给签证用户的内容");
            }
        } catch (Exception e) {
            // 异常处理逻辑
        }
    }

    private void payPrdOfHotelVerify(OrderInfo orderInfo) {
        // 各种酒店订单支付前的检查 ...... 候选人不用关系内部逻辑
    }

    private void payAfterOfVisaBusiness(long payId, OrderInfo orderInfo) {
        // 各种签证订单支付后的逻辑 ...... 候选人不用关系内部逻辑
    }


}
enum OrderStatus {
    PAYING(1, "支付中"),
    PAY_COMPLETED(4, "完成支付"),
    REFUND(9, "退款");

    private int code;
    private String description;

    OrderStatus(int code, String description) {
        this.code = code;
        this.description = description;
    }

    public int getCode() {
        return code;
    }

    public String getDescription() {
        return description;
    }
}

enum PayType {
    HOTEL("hotel", "酒店订单"),
    TICKETS("tickets", "门票订单"),
    VISA("visa", "签证订单");

    private String code;
    private String description;

    PayType(String code, String description) {
        this.code = code;
        this.description = description;
    }

    public String getCode() {
        return code;
    }

    public String getDescription() {
        return description;
    }
}

// -------------------- 方便候选人本地阅读代码，↓↓↓↓↓↓↓不需要动 --------------------


/**
 * 订单服务类 (方便候选人本地阅读代码, 不需要动)
 */
class OrderService {
    OrderInfo getOrderInfo(String orderNo) {
        return new OrderInfo();
    }

    void updateOrderStatus(String orderNo, int status) {
        // 更新订单逻辑
    }

}

/**
 * 支付服务类 (方便候选人本地阅读代码, 不需要动)
 */
class PayService {

    /**
     * 信用支付
     * @param orderInfo
     */
    long payOfCredit(OrderInfo orderInfo) {
        //  信用支付逻辑，候选人不用理会支付内部逻辑 ...
        return 1;
    }

    /**
     * 支付宝支付
     * @param orderInfo
     */
    long payOfAliPay(OrderInfo orderInfo) {
        //  支付宝支付逻辑，候选人不用理会支付内部逻辑 ...
        return 1;
    }

    /**
     * 未支付成功后关闭
     * @param orderInfo
     */
    public void notPayedToClose(OrderInfo orderInfo) {
        //  支付宝支付逻辑，候选人不用理会支付内部逻辑 ...
    }
}

class NotifyService {
    /**
     * 短信通知
     */
    void sms(String msg) {}
    /**
     * 钉钉通知
     */
    void dingding(String msg) {}
    /**
     * 微信通知
     */
    void wechat(String msg) {}
    /**
     * 邮件通知
     */
    void email(String msg) {}
}


/**
 * 订单类 (方便候选人本地阅读代码, 不需要动)
 */
class OrderInfo {
    private String orderNo;
    private String orderBizType;
    private int status;
    private String anything;

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public String getOrderBizType() {
        return orderBizType;
    }

    public void setOrderBizType(String orderBizType) {
        this.orderBizType = orderBizType;
    }

    public String getAnything() {
        return anything;
    }

    public void setAnything(String anything) {
        this.anything = anything;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }
}